import { API_CONFIG } from '@/api/config'
import { useUserStore } from '@/store/user'
import { useChatStore } from '@/store/chat'
import type { Message } from '@/types'

/**
 * WebSocket管理类
 */
class WebSocketManager {
  private ws: UniApp.SocketTask | null = null
  private url: string
  private reconnectTimer: number | null = null
  private heartbeatTimer: number | null = null
  private reconnectCount: number = 0
  private maxReconnectCount: number = 5
  private heartbeatInterval: number = 30000 // 30秒心跳
  private reconnectInterval: number = 5000 // 5秒重连
  private isManualClose: boolean = false

  constructor() {
    this.url = API_CONFIG.WS_URL
  }

  /**
   * 连接WebSocket
   */
  connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      const userStore = useUserStore()
      const token = userStore.token

      if (!token) {
        console.error('WebSocket连接失败: 未登录')
        reject(new Error('未登录'))
        return
      }

      // 关闭已有连接
      this.close()

      // 创建新连接
      this.ws = uni.connectSocket({
        url: `${this.url}?token=${token}`,
        success: () => {
          console.log('WebSocket连接创建')
        },
        fail: (err) => {
          console.error('WebSocket连接失败:', err)
          reject(err)
        }
      })

      // 监听打开
      this.ws.onOpen(() => {
        console.log('WebSocket已连接')
        this.reconnectCount = 0
        this.isManualClose = false
        this.startHeartbeat()
        resolve()
      })

      // 监听消息
      this.ws.onMessage((res) => {
        this.handleMessage(res.data)
      })

      // 监听错误
      this.ws.onError((err) => {
        console.error('WebSocket错误:', err)
        this.reconnect()
      })

      // 监听关闭
      this.ws.onClose(() => {
        console.log('WebSocket已关闭')
        this.stopHeartbeat()
        if (!this.isManualClose) {
          this.reconnect()
        }
      })
    })
  }

  /**
   * 发送消息
   */
  send(data: any): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!this.ws) {
        reject(new Error('WebSocket未连接'))
        return
      }

      this.ws.send({
        data: JSON.stringify(data),
        success: () => resolve(),
        fail: (err) => reject(err)
      })
    })
  }

  /**
   * 关闭连接
   */
  close() {
    if (this.ws) {
      this.isManualClose = true
      this.ws.close({
        success: () => {
          console.log('WebSocket连接已关闭')
        }
      })
      this.ws = null
    }
    this.stopHeartbeat()
    this.stopReconnect()
  }

  /**
   * 处理接收到的消息
   */
  private handleMessage(data: string) {
    try {
      const message = JSON.parse(data)

      // 处理不同类型的消息
      switch (message.type) {
        case 'heartbeat':
          // 心跳响应
          break

        case 'message':
          // 新消息
          this.handleNewMessage(message.data)
          break

        case 'notification':
          // 系统通知
          this.handleNotification(message.data)
          break

        default:
          console.log('未知消息类型:', message)
      }
    } catch (err) {
      console.error('消息解析失败:', err)
    }
  }

  /**
   * 处理新消息
   */
  private handleNewMessage(data: Message) {
    const chatStore = useChatStore()
    chatStore.addMessage(data)

    // 显示通知
    uni.showToast({
      title: '收到新消息',
      icon: 'none'
    })

    // 更新消息角标
    this.updateUnreadCount()
  }

  /**
   * 处理系统通知
   */
  private handleNotification(data: any) {
    uni.showToast({
      title: data.message || '系统通知',
      icon: 'none'
    })
  }

  /**
   * 更新未读消息数
   */
  private updateUnreadCount() {
    const chatStore = useChatStore()
    const unreadCount = chatStore.unreadCount

    if (unreadCount > 0) {
      uni.setTabBarBadge({
        index: 2, // 消息tab的索引
        text: String(unreadCount > 99 ? '99+' : unreadCount)
      })
    } else {
      uni.removeTabBarBadge({ index: 2 })
    }
  }

  /**
   * 开始心跳
   */
  private startHeartbeat() {
    this.stopHeartbeat()

    this.heartbeatTimer = setInterval(() => {
      this.send({ type: 'heartbeat', timestamp: Date.now() })
        .catch(err => {
          console.error('心跳发送失败:', err)
        })
    }, this.heartbeatInterval) as unknown as number
  }

  /**
   * 停止心跳
   */
  private stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 重连
   */
  private reconnect() {
    if (this.isManualClose) return

    if (this.reconnectCount >= this.maxReconnectCount) {
      console.error('WebSocket重连次数超限')
      uni.showToast({
        title: '网络连接失败',
        icon: 'none'
      })
      return
    }

    this.stopReconnect()

    this.reconnectTimer = setTimeout(() => {
      console.log(`WebSocket尝试重连 (${this.reconnectCount + 1}/${this.maxReconnectCount})`)
      this.reconnectCount++
      this.connect().catch(err => {
        console.error('WebSocket重连失败:', err)
      })
    }, this.reconnectInterval) as unknown as number
  }

  /**
   * 停止重连
   */
  private stopReconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
  }

  /**
   * 发送聊天消息
   */
  sendChatMessage(conversationId: number, message: {
    contentType: string
    content?: string
    mediaUrl?: string
  }) {
    return this.send({
      type: 'chat',
      conversationId,
      ...message
    })
  }
}

// 导出单例
export const wsManager = new WebSocketManager()

// 导出默认实例
export default wsManager
